package cn.edu.tju.elm.controller;

import cn.edu.tju.core.model.User;
import cn.edu.tju.core.security.service.UserService;
import cn.edu.tju.elm.dto.FoodDto;
import cn.edu.tju.elm.model.Business;
import cn.edu.tju.elm.model.Food;
import cn.edu.tju.elm.repository.BusinessRepository;
import cn.edu.tju.elm.repository.FoodRepository;
import cn.edu.tju.core.model.HttpResult;
//import cn.edu.tju.elb.service.BusinessService;
//import cn.edu.tju.elb.service.FoodService;
import cn.edu.tju.core.security.service.UserService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.security.access.AccessDeniedException;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.server.ResponseStatusException;

import java.util.ArrayList;
import java.util.List;

import java.time.LocalDateTime;

@RestController
@RequestMapping("/api/foods")
@Tag(name = "管理商品")
public class FoodController {
    @Autowired
    private final UserService userService;
    private final FoodRepository foodRepository;
    private final BusinessRepository businessRepository;

    public FoodController(UserService userService, FoodRepository foodRepository, BusinessRepository businessRepository) {
        this.userService = userService;
        this.foodRepository = foodRepository;
        this.businessRepository = businessRepository;
    }

//    @Autowired
//    private FoodService foodService;
//
//    @Autowired
//    private BusinessService businessService;

    @GetMapping("/{id}")
    @Operation(summary = "返回查询到的一条商品记录", method = "GET")
    public ResponseEntity<Food> getFoodById(@PathVariable Long id){
        // 1. 使用 repository 的 findById 方法，它会返回一个 Optional 容器
        Food food = foodRepository.findById(id)
                // 2. 如果容器为空（即找不到），则抛出一个会导致 404 Not Found 响应的异常
                .orElseThrow(() -> new ResponseStatusException(HttpStatus.NOT_FOUND, "Food not found with ID: " + id));

        // 3. 如果找到了，用 ResponseEntity.ok() 包装并返回，状态码为 200 OK
        return ResponseEntity.ok(food);
    }

    @GetMapping("")
    public ResponseEntity<List<Food>> getAllFoods(@RequestParam(name = "business", required = false) Long businessId,
                                              @RequestParam(name = "order", required = false) Long orderId){
        List<Food> foods;

        if (businessId != null) {
            // 如果请求中包含 businessId 参数，则按商家ID查询
            foods = foodRepository.findByBusinessIdAndDeletedFalse(businessId);
        } else {
            // 如果没有 businessId 参数，则查询所有未删除的菜品
            foods = foodRepository.findByDeletedFalse();
        }

        return ResponseEntity.ok(foods);
    }

    @PostMapping("")
    @Operation(summary = "新增一个菜品", description = "为指定的商家新增一个菜品")
    @Transactional
    public HttpResult<Food> addFood(@RequestBody FoodDto foodDto) {
        // 1. 获取当前登录的用户，用于设置 creator/updater 字段
        User currentUser = userService.getUserWithAuthorities()
                .orElseThrow(() -> new AccessDeniedException("User not authenticated"));
        

        if (foodDto.getBusiness() == null || foodDto.getBusiness().getId() == null) {
            throw new ResponseStatusException(HttpStatus.BAD_REQUEST, "请求体中必须包含有效的商家ID (business.id)");
        }
        
        // 2. 找到这个新菜品将要归属的 Business 实体
        Business business = businessRepository.findById(foodDto.getBusiness().getId())
                .orElseThrow(() -> new ResponseStatusException(HttpStatus.NOT_FOUND, "Business not found with ID: " + foodDto.getBusiness().getId()));

        // !! 安全性检查!!
        // 检查当前用户是否有权限为这个商家添加菜品。
        // 例如：if (!business.getOwnerId().equals(currentUser.getId())) { throw new AccessDeniedException("权限不足"); }
        // 暂时先跳过这个复杂的检查。

        // 3. 创建一个新的 Food 实体，并用 DTO 中的数据填充它
        Food newFood = new Food();
        newFood.setFoodName(foodDto.getFoodName());
        newFood.setFoodExplain(foodDto.getFoodExplain());
        newFood.setFoodImg(foodDto.getFoodImg());
        newFood.setFoodPrice(foodDto.getFoodPrice());
        
        // 4. 设置与商家的关联
        newFood.setBusiness(business);

        // 5. 设置审计字段
        newFood.setCreator(currentUser.getId());
        newFood.setUpdater(currentUser.getId());
        newFood.setCreateTime(LocalDateTime.now());
        newFood.setUpdateTime(LocalDateTime.now());
        newFood.setDeleted(false);

        // 6. 将新菜品保存到数据库
        Food savedFood = foodRepository.save(newFood);

        return HttpResult.success(savedFood);
    }

    @PutMapping("/{id}")
    @Operation(summary = "更新菜品信息", description = "根据ID更新菜品信息")
    @Transactional
    public ResponseEntity<Food> updateFood(@PathVariable Long id, @RequestBody FoodDto foodDto) {
        // 打印接收到的请求数据
        System.out.println("收到更新商品请求，商品ID: " + id);
        System.out.println("商品名称: " + foodDto.getFoodName());
        System.out.println("商品价格: " + foodDto.getFoodPrice());
        System.out.println("商品描述: " + foodDto.getFoodExplain());
        System.out.println("商家ID: " + foodDto.getBusiness().getId());
        System.out.println("备注: " + foodDto.getRemarks());
        
        // 1. 获取当前登录的用户，用于设置updater字段
        User currentUser = userService.getUserWithAuthorities()
                .orElseThrow(() -> new AccessDeniedException("User not authenticated"));
        
        System.out.println("当前用户ID: " + currentUser.getId());
        System.out.println("当前用户权限: " + currentUser.getAuthorities());

        // 2. 查找要更新的食品
        Food existingFood = foodRepository.findById(id)
                .orElseThrow(() -> new ResponseStatusException(HttpStatus.NOT_FOUND, "Food not found with ID: " + id));
        
        // 3. 获取商品所属的商家
        Business business = existingFood.getBusiness();
        System.out.println("商家ID: " + business.getId());
        System.out.println("商家所有者: " + (business.getBusinessOwner() != null ? business.getBusinessOwner().getId() : "null"));
        
        // 权限检查：确保操作者是商家所有者或管理员
        if (existingFood.getBusiness().getBusinessOwner() != null && !existingFood.getBusiness().getBusinessOwner().getId().equals(currentUser.getId())) {
            // 也可以增加管理员角色的判断
            throw new AccessDeniedException("您没有权限修改此商家的菜品");
       }
        
        
        // 暂时注释掉权限检查，允许任何已登录用户更新食品
        // 正式环境中应该启用适当的权限检查
        /*
        // 简单权限检查：检查当前用户是否是该商家的所有者
        if (business.getBusinessOwner() != null && !business.getBusinessOwner().getId().equals(currentUser.getId())) {
            // 可以添加更复杂的权限检查，比如检查是否是管理员
            throw new AccessDeniedException("您没有权限修改此菜品");
        }
        */

        // 4. 更新菜品信息
        existingFood.setFoodName(foodDto.getFoodName());
        existingFood.setFoodPrice(foodDto.getFoodPrice());
        existingFood.setFoodExplain(foodDto.getFoodExplain());
        // 更新备注
        existingFood.setRemarks(foodDto.getRemarks());
        
        // 只有当前端提供了图片时才更新
        if (foodDto.getFoodImg() != null) {
            existingFood.setFoodImg(foodDto.getFoodImg());
        }
        
        
        
        // 如果需要更改商家归属，可以在这里处理
        if (foodDto.getBusiness() != null && foodDto.getBusiness().getId() != null && !foodDto.getBusiness().getId().equals(existingFood.getBusiness().getId())) {
            Long newBusinessId = foodDto.getBusiness().getId();
            Business newBusiness = businessRepository.findById(newBusinessId)
                    .orElseThrow(() -> new ResponseStatusException(HttpStatus.NOT_FOUND, "Business not found with ID: " + newBusinessId));
            existingFood.setBusiness(newBusiness);
        }

        // 5. 更新审计字段
        existingFood.setUpdater(currentUser.getId());
        existingFood.setUpdateTime(LocalDateTime.now());

        // 6. 保存更新后的菜品
        Food updatedFood = foodRepository.save(existingFood);
        
        System.out.println("商品更新成功，ID: " + updatedFood.getId());

        return ResponseEntity.ok(updatedFood);
    }

    @PatchMapping("/{id}")
    @Operation(summary = "局部更新菜品信息", description = "只更新请求体中提供的字段")
    @Transactional
    public HttpResult<Food> patchFood(@PathVariable Long id, @RequestBody FoodDto foodDto) {
        // 1. 获取当前登录的用户
        User currentUser = userService.getUserWithAuthorities()
                .orElseThrow(() -> new AccessDeniedException("User not authenticated"));

        // 2. 查找要更新的食品
        Food existingFood = foodRepository.findById(id)
                .orElseThrow(() -> new ResponseStatusException(HttpStatus.NOT_FOUND, "Food not found with ID: " + id));

        // 3. 权限检查：确保操作者是商家所有者或管理员
        // 你可以根据需要添加更复杂的权限，比如管理员也能修改
        if (existingFood.getBusiness().getBusinessOwner() != null && !existingFood.getBusiness().getBusinessOwner().getId().equals(currentUser.getId())) {
            throw new AccessDeniedException("您没有权限修改此商家的菜品");
        }

        // 4. --- PATCH 核心逻辑：逐个检查DTO中的字段是否为null，如果不为null则更新 ---
        boolean isUpdated = false;

        if (foodDto.getFoodName() != null) {
            existingFood.setFoodName(foodDto.getFoodName());
            isUpdated = true;
        }
        if (foodDto.getFoodPrice() != null) {
            existingFood.setFoodPrice(foodDto.getFoodPrice());
            isUpdated = true;
        }
        if (foodDto.getFoodExplain() != null) {
            existingFood.setFoodExplain(foodDto.getFoodExplain());
            isUpdated = true;
        }
        if (foodDto.getFoodImg() != null) {
            existingFood.setFoodImg(foodDto.getFoodImg());
            isUpdated = true;
        }
        if (foodDto.getRemarks() != null) {
            existingFood.setRemarks(foodDto.getRemarks());
            isUpdated = true;
        }
        
        // 如果需要允许 PATCH 请求更改商家归属，可以加上这段逻辑
        if (foodDto.getBusiness() != null && foodDto.getBusiness().getId() != null && !foodDto.getBusiness().getId().equals(existingFood.getBusiness().getId())) {
            Long newBusinessId = foodDto.getBusiness().getId();
            Business newBusiness = businessRepository.findById(newBusinessId)
                    .orElseThrow(() -> new ResponseStatusException(HttpStatus.NOT_FOUND, "Business not found with ID: " + newBusinessId));
            existingFood.setBusiness(newBusiness);
            isUpdated = true;
        }

        // 5. 如果有任何字段被更新了，则更新审计信息并保存
        if (isUpdated) {
            existingFood.setUpdater(currentUser.getId());
            existingFood.setUpdateTime(LocalDateTime.now());
            foodRepository.save(existingFood);
        }

        // 6. 返回更新后的完整数据
        return HttpResult.success(existingFood);
    }

    @DeleteMapping("/{id}")
    @Operation(summary = "删除菜品", description = "根据ID删除菜品(软删除)")
    @Transactional
    public HttpResult<Void> deleteFood(@PathVariable Long id) {
        // 1. 获取当前登录的用户
        User currentUser = userService.getUserWithAuthorities()
                .orElseThrow(() -> new AccessDeniedException("User not authenticated"));
        
        // 2. 查找要删除的食品
        Food existingFood = foodRepository.findById(id)
                .orElseThrow(() -> new ResponseStatusException(HttpStatus.NOT_FOUND, "Food not found with ID: " + id));
        
        // 3. 权限检查：确保操作者是商家所有者或管理员
        if (existingFood.getBusiness().getBusinessOwner() != null && 
            !existingFood.getBusiness().getBusinessOwner().getId().equals(currentUser.getId())) {
            // 也可以增加管理员角色的判断
            throw new AccessDeniedException("您没有权限删除此商家的菜品");
        }
        
        // 4. 执行软删除操作
        existingFood.setDeleted(true);
        existingFood.setUpdater(currentUser.getId());
        existingFood.setUpdateTime(LocalDateTime.now());
        foodRepository.save(existingFood);
        
        return HttpResult.success(null);
    }
}
